package com.oanda.blackberry.view;

import net.rim.device.api.system.Bitmap;
import net.rim.device.api.ui.Field;
import net.rim.device.api.ui.FieldChangeListener;
import net.rim.device.api.ui.Font;
import net.rim.device.api.ui.MenuItem;
import net.rim.device.api.ui.UiApplication;
import net.rim.device.api.ui.component.Dialog;
import net.rim.device.api.ui.component.EditField;
import net.rim.device.api.ui.component.Menu;
import net.rim.device.api.ui.component.SeparatorField;
import net.rim.device.api.ui.container.HorizontalFieldManager;
import net.rim.device.api.ui.decor.BackgroundFactory;

import com.oanda.blackberry.restapi.Quote;
import com.oanda.blackberry.restapi.Symbol;
import com.oanda.blackberry.restapi.TradeListResponse;
import com.oanda.blackberry.ui.BitmapButtonField;
import com.oanda.blackberry.ui.ColoredEditField;
import com.oanda.blackberry.ui.OandaMainScreen;
import com.oanda.blackberry.ui.PriceEditField;
import com.oanda.blackberry.ui.SpacerField;
import com.oanda.blackberry.ui.SpacerManager;
import com.oanda.blackberry.util.AbstractViewPanel;
import com.oanda.blackberry.util.DefaultController;
import com.oanda.blackberry.util.Model;
import com.oanda.blackberry.util.PropertyChangeEvent;
import com.oanda.blackberry.util.log.Logger;

public class TradesDetailsView implements AbstractViewPanel {
    DefaultController controller;
    BitmapButtonField submit;
    ColoredEditField id;
    ColoredEditField units;
    EditField dir;
    EditField symbol;
    ColoredEditField price;
    ColoredEditField sl;
    ColoredEditField tp;
    ColoredEditField ts;
    ColoredEditField lb;
    ColoredEditField ub;
    PriceEditField quoteField;
    Symbol lastSymbol;
    OandaMainScreen screen;
    boolean isModify = false;

    boolean isSubmitAdded = false;

    MenuItem changeTrade = new MenuItem("Change Trade", 10, 1000) {
        public void run() {
            TradesDetailsView.this.changeTrade();
        }
    };

    MenuItem modifyTrade = new MenuItem("Modify", 10, 1001) {
        public void run() {
            TradesDetailsView.this.modify();
        }
    };

    MenuItem back = new MenuItem("Back", 10, 1001) {
        public void run() {
            TradesDetailsView.this.onClose();
        }
    };

    public TradesDetailsView(DefaultController controller) {
        this.controller = controller;
    }

    private void init() {
        this.screen = new OandaMainScreen() {
            protected void makeMenu(Menu menu, int instance) {
                if (TradesDetailsView.this.isModify)
                    menu.add(TradesDetailsView.this.changeTrade);
                else {
                    menu.add(TradesDetailsView.this.modifyTrade);
                }
                menu.add(TradesDetailsView.this.back);
            }
        };
        this.isSubmitAdded = false;
        this.isModify = false;

        initFields();

        this.screen.getMainManager()
                .setBackground(BackgroundFactory.createSolidBackground(4473924));

        createBackground();
        setFonts();

        this.screen.updateTitle("Trade Details View");

        this.screen.add(new SpacerField(480, 25));

        this.screen.add(this.quoteField);

        HorizontalFieldManager details = new HorizontalFieldManager(1152921504606846976L);
        SpacerManager d1 = new SpacerManager(240, 74);
        SpacerManager d2 = new SpacerManager(240, 74);
        this.screen.add(details);

        this.id.setMargin(10, 0, 0, 15);
        this.units.setMargin(8, 0, 0, 15);

        details.add(d1);
        details.add(d2);
        d1.add(this.id);
        d1.add(this.units);

        this.price.setMargin(20, 0, 0, 30);
        d2.add(this.price);

        this.screen.add(new SpacerManager(480, 10));
        this.screen.add(new SeparatorField());
        this.screen.add(new SpacerManager(480, 5));

        HorizontalFieldManager limits = new HorizontalFieldManager(1152921504606846976L);
        SpacerManager v1 = new SpacerManager(240, 122);
        SpacerManager v2 = new SpacerManager(240, 122);
        limits.add(v1);
        limits.add(v2);
        this.screen.add(limits);

        this.tp.setPadding(10, 8, 8, 15);
        this.sl.setPadding(10, 8, 8, 15);
        this.ts.setPadding(10, 8, 8, 15);
        this.ub.setPadding(10, 8, 8, 10);
        this.lb.setPadding(10, 8, 8, 10);

        v1.add(this.tp);
        v1.add(this.sl);
        v1.add(this.ts);

        v2.add(this.ub);
        v2.add(this.lb);

        this.submit.setChangeListener(new FieldChangeListener() {
            public void fieldChanged(Field field, int context) {
                TradesDetailsView.this.changeTrade();
            }
        });
    }

    private void initFields() {
        this.submit = new BitmapButtonField(Bitmap.getBitmapResource("submit-button-hover.png"),
                Bitmap.getBitmapResource("submit-button-p8.png"), "Submit", 12884967424L);

        this.id = new ColoredEditField(16119285, "Trade #: ", "", 25, 45035996273704960L);
        this.units = new ColoredEditField(16119285, "Units", "", 15, 83886080L);
        this.dir = new EditField("Dir: ", "", 15, 45035996273704960L);

        this.symbol = new EditField("Symbol: ", "", 15, 45035996273704960L);
        this.price = new ColoredEditField(16119285, "Price: ", "", 25, 251658240L);

        this.sl = new ColoredEditField(14287362, "SL: ", "", 14, 9007199506399232L);
        this.tp = new ColoredEditField(8956419, "TP: ", "", 14, 9007199506399232L);
        this.ts = new ColoredEditField(16762898, "TS: ", "", 14, 9007199506399232L);

        this.lb = new ColoredEditField(8936959, "LB: ", "", 14, 9007199506399232L);
        this.ub = new ColoredEditField(8936959, "UB: ", "", 14, 9007199506399232L);

        this.quoteField = new PriceEditField(0L, null, 0);
    }

    private void setTradesDetailsQuote(Quote quote) {
        UiApplication.getUiApplication().invokeLater(new Runnable() {
            private Quote quote;

            public void run() {
                TradesDetailsView.this.quoteField.setQuote(this.quote);
                Symbol symbol = Model.getModel().getSymbol(this.quote.getSymbol());
                if ((TradesDetailsView.this.ts != null)
                        && (TradesDetailsView.this.ts.getText() != null)
                        && (TradesDetailsView.this.ts.getText().length() > 0) && (symbol != null)) {
                    TradesDetailsView.this.lastSymbol = symbol;
                    String tsT = TradesDetailsView.this.ts.getText();
                    double tsD = Double.parseDouble(tsT);
                    double d = symbol.getPips(tsD);
                    TradesDetailsView.this.ts.setText(Double.toString(d));
                }
                TradesDetailsView.this.screen.invalidate();
            }
        });
    }

    private void setTradesDetails(TradeListResponse trade) {
        if (trade == null) {
            DefaultController.inform("no trades details");
        }

        UiApplication.getUiApplication().invokeLater(new Runnable() {
            private TradeListResponse trade;

            public void run() {
                if (this.trade != null) {
                    TradesDetailsView.this.id.setText(Long.toString(this.trade.getId()));
                    TradesDetailsView.this.units.setLabel(Integer.toString(this.trade.getUnits())
                            + " UNITS");
                    TradesDetailsView.this.dir.setText(this.trade.getDir());
                    TradesDetailsView.this.symbol.setText(this.trade.getSymbol());
                    TradesDetailsView.this.price.setText(Double.toString(this.trade.getPrice()));
                    if (this.trade.getDir().equalsIgnoreCase("L"))
                        TradesDetailsView.this.price.setLabel("LONG @ ");
                    else {
                        TradesDetailsView.this.price.setLabel("SHORT @ ");
                    }

                    String sL = Double.toString(this.trade.getStop_loss());
                    if ((sL == null) || ((sL != null) && (sL.length() == 0))) {
                        sL = "---";
                    }

                    String tP = Double.toString(this.trade.getTake_profit());
                    if ((tP == null) || ((tP != null) && (tP.length() == 0))) {
                        tP = "---";
                    }

                    String tS = Double.toString(this.trade.getTrailing_stop());
                    if ((tS == null) || ((tS != null) && (tS.length() == 0))) {
                        tS = "---";
                    }
                    TradesDetailsView.this.sl.setText(sL);
                    TradesDetailsView.this.tp.setText(tP);
                    TradesDetailsView.this.ts.setText(tS);
                }
            }
        });
    }

    protected void onUiEngineAttached(boolean attached) {
        if (!attached) {
            initComponents();
        }
    }

    public void modelPropertyChange(PropertyChangeEvent evt) {
        if (evt.getPropertyName().equals("setTradesDetails")) {
            if ((evt.getNewValue() != null) && ((evt.getNewValue() instanceof TradeListResponse)))
                setTradesDetails((TradeListResponse) evt.getNewValue());
        } else if (evt.getPropertyName().equals("showTradesDetailsView")) {
            init();
            this.controller.pushScreen(this.screen);
        } else if (evt.getPropertyName().equals("setTradesDetailsQuote")) {
            if ((evt.getNewValue() != null) && ((evt.getNewValue() instanceof Quote)))
                setTradesDetailsQuote((Quote) evt.getNewValue());
        } else if (evt.getPropertyName().equals("hideTradesDetailsView")) {
            onClose();
        }
    }

    private void changeTrade() {
        if (4 == Dialog.ask(3, "Are you sure you want to change this trade?")) {
            String tradeId = getTradeId();
            String accountId = getAccountId();
            String optStopLoss = getOptStopLoss();
            String optTakeProfit = getOptTakeProfit();
            String optTrailingStop = getOptTrailingStop();

            if ((this.lastSymbol != null) && (optTrailingStop != null)
                    && (optTrailingStop.length() > 0)) {
                double d = Double.parseDouble(optTrailingStop);
                double tsInPippettes = this.lastSymbol.getPippettes(d);
                int tsInt = (int) tsInPippettes;
                optTrailingStop = Integer.toString(tsInt);
            }
            this.controller.changeTrade(tradeId, accountId, optStopLoss, optTakeProfit,
                    optTrailingStop);
        }
    }

    private String getTradeId() {
        return this.id.getText();
    }

    private String getAccountId() {
        return Model.getModel().getActiveAccountId();
    }

    private String getOptStopLoss() {
        String stopLoss = this.sl.getText();
        double sl = (0.0D / 0.0D);
        if ((stopLoss != null) && (stopLoss.length() > 0))
            try {
                sl = Double.parseDouble(stopLoss);
                if (sl == 0.0D)
                    return "";
            } catch (NumberFormatException ne) {
                DefaultController.inform("error in parsing stop loss to double");
            }
        else {
            stopLoss = "";
        }
        return stopLoss;
    }

    private String getOptTrailingStop() {
        String trailingStop = this.ts.getText();
        double ts = (0.0D / 0.0D);
        if ((trailingStop != null) && (trailingStop.length() > 0))
            try {
                ts = Double.parseDouble(trailingStop);
                if (ts == 0.0D)
                    return "";
            } catch (NumberFormatException ne) {
                DefaultController.inform("error in parsing trailing stop to double");
            }
        else {
            trailingStop = "";
        }
        return trailingStop;
    }

    private String getOptTakeProfit() {
        String takeProfit = this.tp.getText();
        double takeP = (0.0D / 0.0D);
        if ((takeProfit != null) && (takeProfit.length() > 0))
            try {
                takeP = Double.parseDouble(takeProfit);
                if (takeP == 0.0D)
                    return "";
            } catch (NumberFormatException ne) {
                DefaultController.inform("error in parsing trailing stop to double");
            }
        else {
            takeProfit = "";
        }
        return takeProfit;
    }

    public boolean onClose() {
        Runnable r = new Runnable() {
            public void run() {
                TradesDetailsView.this.freeResourses();
                TradesDetailsView.this.controller.popScreen(TradesDetailsView.this.screen);
                TradesDetailsView.this.screen = null;
            }
        };
        this.controller.invokeLater(r);
        return true;
    }

    private void createBackground() {
        Bitmap bg = Bitmap.getBitmapResource("single-quote-header-480x320.png");
        this.screen.getMainManager().setBackground(BackgroundFactory.createBitmapBackground(bg));
    }

    private void setFonts() {
        Font font = DefaultController.getComponentFont();
        this.id.setFont(font);
        this.units.setFont(font);
        this.price.setFont(font);

        this.ub.setFont(font);
        this.lb.setFont(font);

        this.tp.setFont(font);
        this.ts.setFont(font);

        this.sl.setFont(font);

        this.units.setFont(font.derive(1, font.getHeight() + 2));
    }

    private void modify() {
        this.isModify = true;

        setFieldsBg();

        setFieldsToEditable();

        addSubmit();
    }

    private void setFieldsBg() {
        Bitmap bg = Bitmap.getBitmapResource("limit-bg-transparent-221x35.png");
        this.tp.setBackground(BackgroundFactory.createBitmapBackground(bg));
        this.ts.setBackground(BackgroundFactory.createBitmapBackground(bg));
        this.ub.setBackground(BackgroundFactory.createBitmapBackground(bg));
        this.lb.setBackground(BackgroundFactory.createBitmapBackground(bg));
        this.sl.setBackground(BackgroundFactory.createBitmapBackground(bg));
    }

    private void setFieldsToEditable() {
        this.tp.setLabel("TP:       ");
        this.ts.setLabel("TS:       ");
        this.ub.setLabel("UB:       ");
        this.lb.setLabel("LB:       ");
        this.sl.setLabel("SL:       ");
        this.tp.setEditable(true);
        this.ts.setEditable(true);
        this.ub.setEditable(true);
        this.lb.setEditable(true);
        this.sl.setEditable(true);
        this.screen.invalidate();
    }

    private void initComponents() {
        Logger.log("initCompo");

        Logger.log("initCompo0");
        if ((this.tp != null) && (this.ts != null) && (this.ub != null) && (this.lb != null)
                && (this.sl != null)) {
            this.tp.setLabel("TP: ");
            this.ts.setLabel("TS: ");
            this.ub.setLabel("UB: ");
            this.lb.setLabel("LB: ");
            this.sl.setLabel("SL: ");
            this.tp.setEditable(false);
            this.ts.setEditable(false);
            this.ub.setEditable(false);
            this.lb.setEditable(false);
            this.sl.setEditable(false);
            this.tp.setBackground(null);
            this.ts.setBackground(null);
            this.ub.setBackground(null);
            this.lb.setBackground(null);
            this.sl.setBackground(null);
        }
        Logger.log("initCompo1");
        if ((this.isSubmitAdded) && (this.screen != null)) {
            this.screen.delete(this.submit);
            this.isSubmitAdded = false;
        }
        Logger.log("initCompo2");
    }

    private void addSubmit() {
        this.isSubmitAdded = true;
        this.screen.add(this.submit);
    }

    private void freeResourses() {
        Logger.log("free res bg");
        initComponents();

        if ((this.screen != null) && (this.screen.getMainManager() != null)) {
            this.screen.getMainManager().setBackground(null);
        }
        this.tp = null;
        this.ts = null;
        this.ub = null;
        this.lb = null;
        this.sl = null;
        this.submit = null;
        this.lastSymbol = null;
        this.isModify = false;
        this.isSubmitAdded = false;
    }
}
